﻿#pragma once
#include "zyCtrol.h"
#include "zyEditBox.h"
#include "zyLmageList.h"
#include "zyWidget.h"
#include "zyListBox.h"
#include "zyDialogBox.h"
#include "zyButton.h"


namespace BlackMoonUI {
	#define TVP_GLYPH 2
	#define GLPS_CLOSED 1
	#define GLPS_OPENED 2
	#define BP_PUSHBUTTON 1
	#define PBS_NORMAL 1
	#define CP_DROPDOWNBUTTON 1
	#define CBXS_NORMAL 1
	struct PropertyGrid_item {
		std::wstring Value; // 内部，切勿修改
		LPARAM lParam = -1; // 标志位/列表内部使用，切勿修改
		int State = -1;
		std::wstring Name;
		int Type = -1;
		int TextColor = -1;
		int Level = -1;
		PropertyGrid_item* Parent = nullptr;
		std::vector<PropertyGrid_item*>* Childs = nullptr;
		int currentIndex = 0; // 存储当前选中索引 列表或逻辑
		LPARAM userData = -1;
	};

	class zyPropertyGrid : public  zyCtrol
	{
	public:
		zyPropertyGrid();
		~zyPropertyGrid();
		
		static void  WINAPI zyPropertyGrid_Destroy(zyObject* obj);
		static LRESULT WINAPI zyPropertyGrid_WndProc(zyObject* obj, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL* bHandled);
		static LRESULT WINAPI zyPropertyGrid_ChildWndProc(zyObject* obj, HWND hWnd, UINT message, WPARAM wParam, 
			LPARAM lParam, BOOL* bHandle);
		BOOL 创建(HWND 参数_父窗口, const std::wstring& 参数_标题 = L"", POINT 参数_位置 = POINT{ 0, 0 }, 
			POINT 参数_尺寸 = POINT{ 60, 120 },int 参数_ID = 0, int 参数_窗口风格 = 0, int 参数_扩展风格 = 0,
			const std::wstring & 参数_列头标题1 = L"", const std::wstring& 参数_列头标题2 = L"");
		BOOL 创建(zyWindow& 参数_父窗口, const std::wstring& 参数_标题 = L"", POINT 参数_位置 = POINT{ 0, 0 }, 
			POINT 参数_尺寸 = POINT{ 60, 120 },int 参数_ID = 0, int 参数_窗口风格 = 0, int 参数_扩展风格 = 0, 
			const std::wstring& 参数_列头标题1 = L"", const std::wstring& 参数_列头标题2 = L"");
		void 背景色(ARGB 参数_背景色);
		ARGB 背景色();
		bool 绑定(HWND 参数_父窗口, int 参数_资源ID, bool 参数_使用默认字体);
		bool 绑定窗口句柄(HWND 参数_窗口句柄);
		PropertyGrid_item* 插入项目_分组(int 参数_索引, const std::wstring& 参数_名称, LPARAM 参数_项目数值 = -1);
		PropertyGrid_item* 插入项目_文本(int 参数_索引, PropertyGrid_item* 参数_父项目句柄, const std::wstring& 参数_名称, 
			const std::wstring& 参数_值, LPARAM 参数_项目数值 = -1);
		PropertyGrid_item* 插入项目_长文本(int 参数_索引, PropertyGrid_item* 参数_父项目句柄, const std::wstring& 参数_名称,
			const std::wstring& 参数_值, LPARAM 参数_项目数值 = -1);

		PropertyGrid_item* 插入项目_列表(int 参数_索引, PropertyGrid_item* 参数_父项目句柄, const std::wstring& 参数_名称,
			LPARAM 参数_项目数值 = -1);
		//这里的参数_值:-1：表示空，0：假；1：真，默认为：-1
		PropertyGrid_item* 插入项目_逻辑(int 参数_索引, PropertyGrid_item* 参数_父项目句柄, const std::wstring& 参数_名称, 
			int 参数_值 = 0, LPARAM 参数_项目数值 = -1);
		//这里的参数_值:是一个32位整数
		PropertyGrid_item* 插入项目_标志位(int 参数_索引, PropertyGrid_item* 参数_父项目句柄, const std::wstring& 参数_名称,
			int 参数_值, LPARAM 参数_项目数值 = -1);
		//这里的参数_值:是RGB颜色
		PropertyGrid_item* 插入项目_颜色(int 参数_索引, PropertyGrid_item* 参数_父项目句柄, const std::wstring& 参数_名称,
			int 参数_值, LPARAM 参数_项目数值 = -1);
		PropertyGrid_item* 插入项目_字体(int 参数_索引, PropertyGrid_item* 参数_父项目句柄, const std::wstring& 参数_名称,
			const std::wstring& 参数_值, LPARAM 参数_项目数值 = -1);
		PropertyGrid_item* 插入项目_图片(int 参数_索引, PropertyGrid_item* 参数_父项目句柄, const std::wstring& 参数_名称,
			const std::wstring& 参数_值, LPARAM 参数_项目数值 = -1);
		int 列表_添加项目(PropertyGrid_item* 参数_父项目句柄, const std::wstring& 参数_名称, LPARAM 参数_项目数值 = -1);
		int 列表_取项目总数(PropertyGrid_item* 参数_父项目句柄);
		std::wstring 列表_取项目文本(PropertyGrid_item* 参数_父项目句柄, int 参数_索引);
		LPARAM 列表_取项目数值(PropertyGrid_item* 参数_父项目句柄, int 参数_索引);
		bool 列表_删除项目(PropertyGrid_item* 参数_父项目句柄, int 参数_索引);
		bool 列表_清空项目(PropertyGrid_item* 参数_父项目句柄);
		bool 列表_置项目文本(PropertyGrid_item* 参数_父项目句柄, int 参数_索引, const std::wstring& 参数_文本);
		bool 列表_置项目数值(PropertyGrid_item* 参数_父项目句柄, int 参数_索引, LPARAM 参数_数值);
		int 标志位_添加分组(PropertyGrid_item* 参数_父项目句柄, const std::wstring& 参数_分组名称);
		int 标志位_添加项目(PropertyGrid_item* 参数_父项目句柄, int 参数_分组索引, const std::wstring& 参数_名称,
			int 参数_值, const std::wstring& 参数_备注);
		std::wstring 标志位_取项目名称(PropertyGrid_item* 参数_父项目句柄,int 参数_分组索引,int 参数_项目索引);
		std::wstring 标志位_取项目备注(PropertyGrid_item* 参数_父项目句柄, int 参数_分组索引, int 参数_项目索引);
		LPARAM 标志位_取项目数值(PropertyGrid_item* 参数_父项目句柄, int 参数_分组索引, int 参数_项目索引);
		bool 标志位_删除项目(PropertyGrid_item* 参数_父项目句柄, int 参数_分组索引, int 参数_项目索引);
		bool 标志位_清空项目(PropertyGrid_item* 参数_父项目句柄, int 参数_分组索引);
		bool 标志位_置分组名称(PropertyGrid_item* 参数_父项目句柄, int 参数_分组索引,const std::wstring& 参数_新名称);
		std::wstring 标志位_取分组名称(PropertyGrid_item* 参数_父项目句柄, int 参数_分组索引);
		bool 标志位_删除分组(PropertyGrid_item* 参数_父项目句柄, int 参数_分组索引);

		bool 删除项目(PropertyGrid_item* 参数_项目句柄);
		void 清空();
		bool 置项目值_文本(PropertyGrid_item* 参数_项目句柄, const std::wstring& 参数_文本);
		bool 置项目值_列表(PropertyGrid_item* 参数_项目句柄, int 参数_索引);
		bool 置项目值_逻辑(PropertyGrid_item* 参数_项目句柄, int 参数_逻辑值);
		bool 置项目值_标志位(PropertyGrid_item* 参数_项目句柄, int 参数_标志值);
		bool 置项目值_颜色(PropertyGrid_item* 参数_项目句柄, int 参数_颜色值);
		bool 置项目值_字体(PropertyGrid_item* 参数_项目句柄, const std::wstring& 参数_字体信息);
		//置项目值_图片
		std::wstring 取项目值_文本(PropertyGrid_item* 参数_项目句柄);
		int 取项目值_列表(PropertyGrid_item* 参数_项目句柄);
		int 取项目值_逻辑(PropertyGrid_item* 参数_项目句柄);
		int 取项目值_标志位(PropertyGrid_item* 参数_项目句柄);
		int 取项目值_颜色(PropertyGrid_item* 参数_项目句柄);
		std::wstring 取项目值_字体(PropertyGrid_item* 参数_项目句柄);
		//取项目值_图片
		std::wstring 取项目名(PropertyGrid_item* 参数_项目句柄);
		int 取项目类型(PropertyGrid_item* 参数_项目句柄);
		PropertyGrid_item* 取父项目(PropertyGrid_item* 参数_项目句柄);
		int 取项目层次(PropertyGrid_item* 参数_项目句柄);
		int 取项目文本色(PropertyGrid_item* 参数_项目句柄);
		int 置项目文本色(PropertyGrid_item* 参数_项目句柄, int 参数_文本色);
		LPARAM 取项目数值(PropertyGrid_item* 参数_项目句柄);
		bool 置项目数值(PropertyGrid_item* 参数_项目句柄, LPARAM 参数_数值);
		int 取项目状态(PropertyGrid_item* 参数_项目句柄);
		int 置项目状态(PropertyGrid_item* 参数_项目句柄, int 参数_状态);
		void 置项目只读(PropertyGrid_item* 参数_项目句柄, bool 参数_是否只读);
		bool 取项目只读(PropertyGrid_item* 参数_项目句柄);
		void 置项目只读仅编辑框(PropertyGrid_item* 参数_项目句柄, bool 参数_是否只读);
		bool 取项目只读仅编辑框(PropertyGrid_item* 参数_项目句柄);
		int 取所有子项目(PropertyGrid_item* 参数_项目句柄, std::vector<PropertyGrid_item*>& 参数_子项目句柄);
		PropertyGrid_item* 取子项目(PropertyGrid_item* 参数_项目句柄, int 参数_索引);
		int 取子项目数(PropertyGrid_item* 参数_项目句柄);
		int 取现行选中项目();
		bool 置现行选中项目(PropertyGrid_item* 参数_项目句柄);
		bool 是否有子项目(PropertyGrid_item* 参数_项目句柄);
		void 重画项目(PropertyGrid_item* 参数_项目句柄);
		bool 置属性名列宽(int 参数_宽度);
		int 取属性名列宽();
		PropertyGrid_item* 寻找项目(PropertyGrid_item* 参数_父项目句柄, const std::wstring& 参数_项目名称);
		PropertyGrid_item* 寻找项目过程(PropertyGrid_item* 参数_父项目, const std::wstring& 参数_项目名称);
		void 触发属性值被改变事件(PropertyGrid_item* 参数_项目句柄);
		//返回值：无 （整数型 hWnd，整数型 项目句柄，逻辑型 是否代码改变【假：表示用户改变；真：表示代码改变】）
		void 事件_属性值被改变(TRegEvent* 参数_事件指针);
		//返回值：整数型【非0表示阻止默认行为】 （整数型 hWnd，整数型 项目句柄，逻辑型 是否为按钮）
		void 事件_项目被点击(TRegEvent* 参数_事件指针);
		//返回值：逻辑型 （整数型 hWnd，整数型 项目句柄） 返回:真允许编辑
		void 事件_将进入编辑(TRegEvent* 参数_事件指针);
		//返回值：无 （整数型 hWnd，整数型 项目句柄）
		void 事件_当前项目被改变(TRegEvent* 参数_事件指针);
		//返回值：无 （整数型 hWnd，整数型 项目句柄, 整数型 列索引）
		void 事件_双击项目(TRegEvent* 参数_事件指针);

	protected:
		void OnNCDestroy();
		void DeletePropertyItem(PropertyGrid_item* item);
		int _GetItemIndex(PropertyGrid_item* 参数_项目句柄);
		void _init(HWND hWnd,const std::wstring& 参数_列头标题1 = L"", const std::wstring& 参数_列头标题2 = L"");
		PropertyGrid_item* _InsertProperty(int index, PropertyGrid_item* parent, const std::wstring& name, int type, int state,
			LPARAM lParam, const std::wstring& Value = L"");

		int LongText_BtnImport_事件_被单击(HWND hWnd, int ID);
		int LongText_BtnCancel_事件_被单击(HWND hWnd, int ID);
		int LongText_BtnOk_事件_被单击(HWND hWnd, int ID);
		int propertyItem_List_OnSelected(HWND hWnd, int ID);
		LRESULT propertyItem_list_Msg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL* bHandle);
		LRESULT propertyItem_Edit_Msg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL* bHand);
		int propertyItem_LongText_Dialog_OnCraete(zyForm* hWnd);
		int propertyItem_LongText_Dialog_OnSize(HWND hWnd, WORD cx, WORD cy);
		
		void propertyItem_DrawNameAndStringValue(HWND hWnd, HDC hdc, PropertyGrid_item* pItem, Gdiplus::Graphics* graphics, int itemSelect, RECT rc, int nameWidth,
			int stringOffset, int stringFontStyle);
		void propertyItem_DrawBackAndLine(Gdiplus::Graphics* graphics,int nameWidth, int itemSelect, RECT rc, int isGroup);
		void propertyItem_DrawExpanding(bool Open, HWND hWnd, HDC hdc,int x,int y,int w,int h);
		void propertyItem_DrawButton(HWND hWnd, HDC hdc, Gdiplus::Graphics* graphics, int type, RECT rc);
		LRESULT propertyItem_OnDraw(PropertyGrid_item* pProperty, LPARAM lParam);

		void zyPropretyGrid_ExpandChange(PropertyGrid_item* pItem, int index);
		LRESULT zyPropretyGrid_OnItemClick(HWND hWnd, int x, int y, int mouseState, BOOL* bHandle);
		void zyPropretyGrid_HideAll();
		void propertyItem_ShowList(PropertyGrid_item* pItem, int index);
		int propertyItem_ShowEdit(PropertyGrid_item* pItem, int iItem, int offsetLeft, int offsetRight);
		int propertyItem_BeginEdit(PropertyGrid_item* pProperty, int iItem);
		int propertyItem_EndEdit(HANDLE grid, HANDLE pItem, int index);
		int propertyItem_OnClick(PropertyGrid_item* pItem, int index, int isOnButton, int mouseState);

		int propertyItem_Flags_OnClick(PropertyGrid_item* pItem, int index, int isOnButton, int mouseState);
		int propertyItem_Flags_Dialog_OnCraete(zyForm* form);
		int propertyItem_Flags_Dialog_OnSize(HWND hWnd, WORD cx, WORD cy);
		int Flags_ListView_CheckChange(HWND hWnd, int 表项索引, int 检查框状态);
		int Flags_BtnOk_事件_被单击(HWND hWnd, int ID);
		int Flags_BtnCancel_事件_被单击(HWND hWnd, int ID);
		struct FlagsItemData {
			std::wstring pitemName;
			int pitemValue;
			std::wstring pitemRemark;
		};
		struct FlagsItem {
			std::wstring pitemName;
			std::vector<FlagsItemData>* pListlItemData;
		};
		struct FlagsListItemData {
			std::vector<FlagsItem>* pListString;
			std::vector<LPARAM>* pListlParam;
			~FlagsListItemData() {
				delete pListString;
				delete pListlParam;
			}
		};
		struct ListItemData {
			std::vector<std::wstring>* pListString;
			std::vector<LPARAM>* pListlParam;
			~ListItemData() {
				delete pListString;
				delete pListlParam;
			}
		};
	};

}

